package yogaService

import (
	"duoke/model"
	"duoke/model/yogaModel"
	"duoke/service/common"
	utils "duoke/utils/common"
	"duoke/utils/gconv"
	"duoke/utils/gjson"
	"duoke/utils/redislib"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/v2/os/gtime"
	"time"
	"xorm.io/xorm"
)

var Home = new(homeService)

type homeService struct{}

func (s *homeService) List(c *gin.Context, id int) (*yogaModel.RspHomeList, error) {
	redisKey := fmt.Sprintf("home_list_%d", id)
	var m yogaModel.RspHomeList
	val := redislib.Redis.Get(c, redisKey).Val()
	if val != "" {
		gjson.Json2StructOrMap(val, &m)
		return &m, nil
	}
	// 获取场地信息
	where := fmt.Sprintf("id=%d", id)
	get, err := common.Tales.Info(where, "*").Table("yoga_venue").Get(&m.VenueInfo)
	if err != nil {
		return nil, err
	}
	if !get {
		return nil, errors.New("场地错误")
	}
	if Venue.IsBusiness(m.VenueInfo.BusinessDate, m.VenueInfo.StartTime, m.VenueInfo.EndTime) {
		m.VenueInfo.IsBusiness = 1
	} else {
		m.VenueInfo.IsBusiness = 2
	}
	// 获取场地轮播图
	var ya []yogaModel.ReqAlbum
	where = fmt.Sprintf("from_id=%d and album_type=3", id)
	err = common.Tales.Info(where, "*").Table("yoga_album").Find(&ya)
	if err != nil {
		return nil, err
	}
	m.VenueBanner = make([]string, 0, len(ya))
	for _, item := range ya {
		m.VenueBanner = append(m.VenueBanner, item.Url)
	}
	// 并发执行以下无依赖的查询
	type result struct {
		err error
	}
	ch := make(chan result, 5)
	// 查询公告
	go func() {
		where = fmt.Sprintf("venue_id=%d and state=1", id)
		err = common.Tales.Info(where, "*").Table("yoga_notice").
			OrderBy("weight desc").Find(&m.Notice)
		ch <- result{err: err}
	}()

	// 查询金牌教师
	go func() {
		where = fmt.Sprintf("venue_id=%d and is_home=%d", id, 2)
		err = common.Tales.Info(where, "*").Table("yoga_teacher").
			OrderBy("weight desc").Find(&m.Teacher)
		ch <- result{err: err}
	}()

	// 查询班课推荐
	go func() {
		where = fmt.Sprintf("venue_id=%d and is_home=%d", id, 2)
		err = common.Tales.Info(where, "*").Table("yoga_course").OrderBy("id desc").
			Find(&m.Course)
		ch <- result{err: err}
	}()

	//  获取推荐课程
	go func() {
		where = fmt.Sprintf("yc.venue_id=%d and yc.is_home=%d and yc.deleted_at is null", id, 2)
		err = common.Tales.Info(where, "yc.id,yc.name,yc.class_type,yc.classroom,yc.difficulty,yc.duration,"+
			"yt.name as teacher_name,yt.pic as teacher_pic,yc.price,yc.cover").Table("yoga_group_class as yc").
			Join("LEFT", "yoga_teacher as yt", "yc.teacher_id = yt.id").OrderBy("yc.id desc").
			Find(&m.GroupClass)
		ch <- result{err: err}
	}()
	// 查询今日课程
	go func() {
		ym := gtime.Now().Format("Ym")
		weekday := gtime.Now().Weekday()
		tody := utils.Common.GetWeekDays(weekday)
		where = fmt.Sprintf("yc.venue_id=%d and yc.class_type in(1,2) and reservation_date=%s and reservation_week=%d",
			id, ym, tody)
		err = common.Tales.Info(where, "yc.*,yt.name as teacher_name,yt.pic as teacher_pic").
			Table("yoga_school_timetable as yd").
			Join("INNER", "yoga_group_class as yc", "yd.class_id = yc.id").
			Join("LEFT", "yoga_teacher as yt", "yc.teacher_id = yt.id").
			OrderBy("buy_count desc").Limit(5).Find(&m.TodayClass)
		ch <- result{err: err}
	}()
	// 收集所有并发结果
	for i := 0; i < 5; i++ {
		res := <-ch
		if res.err != nil {
			return nil, res.err
		}
	}
	redislib.Redis.Set(c, redisKey, gjson.StructOrMap2Json(&m), 60*time.Minute)
	return &m, err
}
func (s *homeService) Search(c *gin.Context, req map[string]interface{}) (*[]yogaModel.RspHome,
	int64, error) {
	albumType := gconv.Int(req["home_type"])
	name := gconv.String(req["name"])
	if albumType == 0 {
		return nil, 0, errors.New("参数缺失【home_type】")
	}
	pageNo := gconv.Int(req["pageNo"])
	pageSize := gconv.Int(req["pageSize"])
	var session *xorm.Session
	switch albumType {
	case 1:
		session = common.Tales.List(c, &model.ReqList{
			PageNo:   pageNo,
			PageSize: pageSize,
			Keyword:  name,
		}).Table("yoga_notice")
	case 2, 3:
		session = common.Tales.List(c, &model.ReqList{
			PageNo:   pageNo,
			PageSize: pageSize,
			Keyword:  name,
		}).Table("yoga_teacher")
	case 4:
		session = common.Tales.List(c, &model.ReqList{
			PageNo:   pageNo,
			PageSize: pageSize,
			Keyword:  name,
		}).Table("yoga_course")
	case 5:
		session = common.Tales.List(c, &model.ReqList{
			PageNo:   pageNo,
			PageSize: pageSize,
			Keyword:  name,
		}).Table("yoga_group_class")
	case 6:
		session = common.Tales.List(c, &model.ReqList{
			PageNo:   pageNo,
			PageSize: pageSize,
			Keyword:  name,
		}).Table("yoga_venue")
	default:
		return nil, 0, errors.New("参数错误【home_type】")
	}
	var m []yogaModel.RspHome
	count, err := session.FindAndCount(&m)
	return &m, count, err
}
